#pragma once

#ifndef __HWINSTDCTRLS_H__
#define __HWINSTDCTRLS_H__

#include "hwincontrol.h"
#include "hwinmenu.h"

namespace harlinn
{
    namespace windows
    {
        class Range
        {
            UINT start;
            UINT end;
        public:
            Range()
                : start(0),
                  end(0)
            {}

            Range(UINT theStart, UINT theEnd)
                : start(theStart),
                  end(theEnd)
            {
                if (end < start)
                {
                    std::swap(start,end);
                }
            }

            UINT Start() const { return start; }
            Range& SetStart(UINT theValue ) {start = theValue; if(end < start) { end = start; } return *this; }
            UINT End() const { return end; }
            Range& SetEnd(UINT theValue ) { end = theValue; if(end < start) { start = end; } return *this; }

            Range& SetRange(UINT theStart, UINT theEnd)
            {
                start = theStart;
                end = theEnd;
                if (end < start)
                {
                    std::swap(start,end);
                }
            }

            UINT Length(  ) const { return end - start; }


        };


        enum class CheckState : int
        {
            Unchecked = 0x0000,
            Checked = 0x0001,
            Indeterminate = 0x0002
        };


        enum class ImageListColor : int
        {
            ColorDefault = 0x00000000,
            Color4 = 0x00000004,
            Color8 = 0x00000008,
            Color16 = 0x00000010,
            Color24 = 0x00000018,
            Color32 = 0x00000020,
            ColorDDB = 0x000000FE
        };

        enum class ImageListFlags : int
        {
            Mask = 0x00000001,
            Mirror = 0x00002000,
            PerItemMirror = 0x00008000,
            OriginalSize = 0x00010000
        };
        DEFINE_ENUM_FLAG_OPERATORS(ImageListFlags)

        enum class ImageListDrawFlags : int
        {
            Normal              = 0x00000000,
            Transparent         = 0x00000001,
            Mask                = 0x00000010,
            Image               = 0x00000020,
            Rop                 = 0x00000040,
            Blend25             = 0x00000002,
            Blend50             = 0x00000004,
            OverlayMask         = 0x00000F00,
            PreserveAlpha       = 0x00001000,
            Scale               = 0x00002000,
            DpiScale            = 0x00004000,
            Async               = 0x00008000,
            Selected            = 0x00000004,
            Focus               = 0x00000002,
            Blend               = 0x00000004
        };
        DEFINE_ENUM_FLAG_OPERATORS(ImageListDrawFlags)

        enum class ImageListLoadFlags : int
        {
            DefaultColor     = 0x00000000,
            Monochrome       = 0x00000001,
            LoadFromFile     = 0x00000010,
            LoadTransparent  = 0x00000020,
            DefaultSize      = 0x00000040,
            LoadMap3DColors  = 0x00001000,
            CreateDibSection = 0x00002000,
            Shared           = 0x00008000
        };
        DEFINE_ENUM_FLAG_OPERATORS(ImageListLoadFlags)

        // --------------------------------------------------------------------
        // ImageList
        // --------------------------------------------------------------------
        class ImageListHandle : public Handle
        {
            HWIN_EXPORT static HIMAGELIST CreateImageList(int elementWidth, int elementHeight,int count, int growBy,ImageListFlags theFlags,ImageListColor color);
        public:
            typedef Handle Base;

            HWIN_EXPORT explicit ImageListHandle(HIMAGELIST theHandle, bool closeHandle = true);
            HWIN_EXPORT ImageListHandle(int elementWidth, int elementHeight,int count, int growBy,ImageListFlags theFlags,ImageListColor color);
            HWIN_EXPORT ~ImageListHandle( );

            
            operator HIMAGELIST() const
            {
                HWIN_TRACE();
                return static_cast<HIMAGELIST>(Value());
            }

            HIMAGELIST GetHIMAGELIST() const
            {
                HWIN_TRACE();
                return static_cast<HIMAGELIST>(Value());
            }

            HWIN_EXPORT ImageListHandle& Add(const BitmapHandle& bitmap);
            HWIN_EXPORT ImageListHandle& Add(const std::shared_ptr<BitmapHandle>& bitmap);
            HWIN_EXPORT ImageListHandle& Add(const BitmapHandle& bitmap, const BitmapHandle& mask);
            HWIN_EXPORT ImageListHandle& Add(const std::shared_ptr<BitmapHandle>& bitmap, const std::shared_ptr<BitmapHandle>& mask);
            HWIN_EXPORT ImageListHandle& Add(const BitmapHandle& bitmap, COLORREF maskColor);
            HWIN_EXPORT ImageListHandle& Add(const std::shared_ptr<BitmapHandle>& bitmap, COLORREF maskColor);
            HWIN_EXPORT ImageListHandle& Move(int indexOfDestinationImage, int indexOfSourceImage);
            HWIN_EXPORT ImageListHandle& Swap(int indexOfFirstImage, int indexOfSecondImage);

            HWIN_EXPORT std::shared_ptr<ImageListHandle> Clone( );

            HWIN_EXPORT const ImageListHandle& BeginDrag(int indexOfTrackImage,int dxHotspot,int dyHotspot) const;
            HWIN_EXPORT const ImageListHandle& BeginDrag(int indexOfTrackImage,const POINT& hotspot) const;
            HWIN_EXPORT static void DragEnter(HWND hwndLock,int x,int y);
            HWIN_EXPORT static void DragEnter(std::shared_ptr<Control> theControl,int x,int y);
            HWIN_EXPORT static void DragLeave(HWND hwndLock);
            HWIN_EXPORT static void DragLeave(std::shared_ptr<Control> theControl);
            HWIN_EXPORT static void DragMove(int x,int y);
            HWIN_EXPORT static void DragShowNolock(bool showImage);
            HWIN_EXPORT static void EndDrag(void);
            HWIN_EXPORT static std::shared_ptr<ImageListHandle> GetDragImage(POINT *ppt,POINT *pptHotspot);


            HWIN_EXPORT const ImageListHandle& Draw(int indexOfImage, HDC hDC, int x, int y, ImageListDrawFlags flags) const;
            HWIN_EXPORT const ImageListHandle& Draw(int indexOfImage, HDC hDC, int x, int y, int dx, int dy, COLORREF background, COLORREF foreground, ImageListDrawFlags flags) const;
            HWIN_EXPORT static void Draw(const IMAGELISTDRAWPARAMS* imagelistDrawOarams);
            HWIN_EXPORT static void Draw(const IMAGELISTDRAWPARAMS& imagelistDrawOarams);

            HWIN_EXPORT COLORREF GetBkColor( ) const;
            HWIN_EXPORT COLORREF BackgroundColor( ) const;

            HWIN_EXPORT std::shared_ptr<IconHandle> GetIcon(int indexOfImage,ImageListDrawFlags flags) const;
            HWIN_EXPORT std::shared_ptr<IconHandle> GetIcon(int indexOfImage) const;

            HWIN_EXPORT void GetIconSize(int* x, int* y) const;
            HWIN_EXPORT void GetIconSize(SIZE& size) const;
            HWIN_EXPORT SIZE GetIconSize() const;

            HWIN_EXPORT void GetImageSize(int* x, int* y) const;
            HWIN_EXPORT void GetImageSize(SIZE& size) const;
            HWIN_EXPORT SIZE GetImageSize() const;

            HWIN_EXPORT int Count() const;
            
            HWIN_EXPORT const ImageListHandle& GetImageInfo(int theImageIndex, IMAGEINFO* imageinfo) const;
            HWIN_EXPORT const ImageListHandle& GetImageInfo(int theImageIndex, IMAGEINFO& imageinfo) const;

            HWIN_EXPORT static std::shared_ptr<ImageListHandle> Load(HINSTANCE hInstance, const wchar_t* name, int imageWidth, int growBy, COLORREF maskColor, ImageListLoadFlags flags);
            HWIN_EXPORT static std::shared_ptr<ImageListHandle> LoadFromFile(const wchar_t* name, int imageWidth, int growBy, COLORREF maskColor, ImageListLoadFlags flags);
            HWIN_EXPORT static std::shared_ptr<ImageListHandle> LoadFromFile(const wchar_t* name, int imageWidth );

            HWIN_EXPORT std::shared_ptr<ImageListHandle> Merge(int i1,HIMAGELIST himl2,int i2,int dx,int dy) const;
            HWIN_EXPORT static std::shared_ptr<ImageListHandle> Merge(HIMAGELIST himl1, int i1,HIMAGELIST himl2,int i2,int dx,int dy);



        };

        // --------------------------------------------------------------------
        // ButtonBase
        // --------------------------------------------------------------------
        class ButtonBase : public Control
        {
            bool autoEllipsis;
        public:
            typedef Control Base;

            HWIN_EXPORT ButtonBase( );
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;
        public:
            

            HWIN_EXPORT bool AutoEllipsis() const;
            HWIN_EXPORT ButtonBase& SetAutoEllipsis(bool theValue);

            

            HWIN_EXPORT ButtonBase& Click();
            HWIN_EXPORT const ButtonBase& GetTextMargin(RECT& margin) const;
            HWIN_EXPORT RECT GetTextMargin( ) const;
            HWIN_EXPORT ButtonBase& SetTextMargin(const RECT& margin);

            HWIN_EXPORT const ButtonBase& GetIdealSize(SIZE& preferredSize) const;
            HWIN_EXPORT SIZE GetIdealSize( ) const;

            boost::signals2::signal<void (Control* sender)> OnClick;
            
        protected:
            HWIN_EXPORT virtual void DoOnSetEnabled(bool theValue);

            HWIN_EXPORT virtual void DoOnClick();
            HWIN_EXPORT virtual void DoOnCommand(Message& message);
            

        };

        // --------------------------------------------------------------------
        // PushButtonBase
        // --------------------------------------------------------------------
        class PushButtonBase : public ButtonBase
        {
            bool isDefault;
        public:
            typedef ButtonBase Base;

            HWIN_EXPORT PushButtonBase( );

            HWIN_EXPORT bool IsDefault() const;
            HWIN_EXPORT PushButtonBase& SetDefault(bool theValue);

            boost::signals2::signal<void (Control* sender,bool theValue)> OnDefaultChanged;
        protected:
            HWIN_EXPORT virtual void DoOnSetDefault(bool theValue);
            HWIN_EXPORT virtual void DoOnDefaultChanged(bool theValue);

        };


        // --------------------------------------------------------------------
        // Button
        // --------------------------------------------------------------------
        class Button : public PushButtonBase
        {
        public:
            typedef PushButtonBase Base;
            HWIN_EXPORT Button( );
            HWIN_EXPORT virtual DWORD GetStyle() const;
        protected:
            HWIN_EXPORT virtual void DoOnSetDefault(bool theValue);
        };


        // --------------------------------------------------------------------
        // DropDownButton
        // --------------------------------------------------------------------
        class DropDownButton : public PushButtonBase
        {
            std::shared_ptr<PopupMenu> popupMenu;
        public:
            typedef PushButtonBase Base;
            HWIN_EXPORT DropDownButton( );
            HWIN_EXPORT virtual DWORD GetStyle() const;

            HWIN_EXPORT std::shared_ptr<PopupMenu> Menu() const;
        protected:
            HWIN_EXPORT virtual void DoOnInitialize( );
            HWIN_EXPORT virtual void DoOnSetDefault(bool theValue);

            HWIN_EXPORT virtual void DoOnNotify(Message& message);
        };

        // --------------------------------------------------------------------
        // CommandButton
        // --------------------------------------------------------------------
        class CommandButton : public PushButtonBase
        {
        public:
            typedef PushButtonBase Base;
            HWIN_EXPORT CommandButton( );
            HWIN_EXPORT virtual DWORD GetStyle() const;
        protected:
            HWIN_EXPORT virtual void DoOnSetDefault(bool theValue);
        };


        // --------------------------------------------------------------------
        // StateButton
        // --------------------------------------------------------------------
        class StateButton : public ButtonBase
        {
            CheckState checkState;
            bool allowGrayed;
        public:
            typedef ButtonBase Base;
            HWIN_EXPORT StateButton( );

            HWIN_EXPORT StateButton& SetCheckState(harlinn::windows::CheckState theCheckState);
            HWIN_EXPORT harlinn::windows::CheckState CheckState() const;

            HWIN_EXPORT bool AllowGrayed() const;
            HWIN_EXPORT StateButton& SetAllowGrayed(bool theValue = true);

            HWIN_EXPORT bool Checked() const;
            HWIN_EXPORT StateButton& SetChecked(bool theValue);
            HWIN_EXPORT StateButton& Toggle();
            
            HWIN_EXPORT virtual void HandleMessage(Message& message);
            boost::signals2::signal<void (Control* sender,harlinn::windows::CheckState theCheckState)> OnCheckStateChanged;
        protected:
            HWIN_EXPORT virtual void DoOnHandleCreated( );
            HWIN_EXPORT virtual void DoOnCheckStateChanged( harlinn::windows::CheckState theCheckState );
            HWIN_EXPORT virtual void DoOnClick();
        };

        // --------------------------------------------------------------------
        // CheckBox
        // --------------------------------------------------------------------
        class CheckBox : public StateButton
        {
            
        public:
            typedef StateButton Base;
            HWIN_EXPORT CheckBox( );
        protected:
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };

        // --------------------------------------------------------------------
        // RadioButton
        // --------------------------------------------------------------------
        class RadioButton : public StateButton
        {
        public:
            typedef StateButton Base;
            HWIN_EXPORT RadioButton( );
        protected:
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        // --------------------------------------------------------------------
        // DateTimePicker
        // --------------------------------------------------------------------
        class DateTimePicker : public Control
        {
        public:
            typedef Control Base;

            HWIN_EXPORT DateTimePicker( );
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
        
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        // --------------------------------------------------------------------
        // GroupBox
        // --------------------------------------------------------------------
        class GroupBox : public Control
        {
        public:
            typedef Control Base;

            HWIN_EXPORT GroupBox( );
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
        
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        // --------------------------------------------------------------------
        // Label
        // --------------------------------------------------------------------
        class Label : public Control
        {
        public:
            typedef Control Base;
            HWIN_EXPORT Label( );
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        // --------------------------------------------------------------------
        // LinkLabel
        // --------------------------------------------------------------------
        class LinkLabel : public Label
        {
        public:
            typedef Label Base;
            HWIN_EXPORT LinkLabel( );
            

            boost::signals2::signal<void (LinkLabel* sender,NMLINK* pNMLINK)> OnClick;
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;

            HWIN_EXPORT virtual void DoOnClick(NMLINK* pNMLINK);
            HWIN_EXPORT virtual void DoOnNotify(Message& message);
        };

        // --------------------------------------------------------------------
        // ListControl
        // --------------------------------------------------------------------
        class ListControl : public Control
        {
        public:
            typedef Control Base;
            HWIN_EXPORT ListControl( );
        };

        // --------------------------------------------------------------------
        // ComboBox
        // --------------------------------------------------------------------
        class ComboBox : public ListControl
        {
        public:
            typedef ListControl Base;
            HWIN_EXPORT ComboBox( );
            
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        // --------------------------------------------------------------------
        // ListBox
        // --------------------------------------------------------------------
        class ListBox : public ListControl
        {
        public:
            typedef ListControl Base;
            HWIN_EXPORT ListBox( );
            
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        // --------------------------------------------------------------------
        // CheckedListBox
        // --------------------------------------------------------------------
        class CheckedListBox : public ListBox
        {
        public:
            typedef ListBox Base;
            HWIN_EXPORT CheckedListBox( );
        protected:
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        enum class HeaderControlItemMask : UINT
        {
            None = 0,
            Width               = 0x0001,
            Height              = 0x0001,
            Text                = 0x0002,
            Format              = 0x0004,
            LParam              = 0x0008,
            Bitmap              = 0x0010,
            Image               = 0x0020,
            DiSetItem           = 0x0040,
            Order               = 0x0080,
            Filter              = 0x0100,
            State               = 0x0200
        };
        DEFINE_ENUM_FLAG_OPERATORS(HeaderControlItemMask)



        enum class HeaderControlItemFormat : int
        {
            Default = 0,
            Left                = 0x0000,
            Right               = 0x0001,
            Center              = 0x0002,
            AlignmentMask       = 0x0003,
            RTLReading          = 0x0004,
            Bitmap              = 0x2000,
            String              = 0x4000,
            OwnerDraw           = 0x8000,
            Image               = 0x0800,
            BitmapOnRight       = 0x1000,
            SortUp              = 0x0400,
            SortDown            = 0x0200,
            CheckBox            = 0x0040,
            Checked             = 0x0080,
            FixedWidth          = 0x0100,
            SplitButton      = 0x1000000
        };
        DEFINE_ENUM_FLAG_OPERATORS(HeaderControlItemFormat)

        enum class HeaderControlItemFilterType
        {
            String = HDFT_ISSTRING,
            Number = HDFT_ISNUMBER,
            DateTime = HDFT_ISDATE,
            None = HDFT_HASNOVALUE
        };

        class HeaderControl;
        class HeaderControlItems;
        // --------------------------------------------------------------------
        // HeaderControlItem
        // --------------------------------------------------------------------
        class HeaderControlItem : public Object
        {
            friend class HeaderControl;
            friend class HeaderControlItems;
            HeaderControlItems* items;

            HeaderControlItemMask mask;
            int     dimension;
            String  text;
            std::shared_ptr<BitmapHandle> bitmap;
            HeaderControlItemFormat  format;
            int     imageIndex;
            int     order;
            HeaderControlItemFilterType filterType;
            String  textFilter;
            int intFilter;
            SYSTEMTIME timeFilter;

            bool IsHandleCreated() const;
            HWND GetControlHandle() const;
            HeaderControl* GetControl() const;
            
        public:
            typedef Object Base;

            HWIN_EXPORT HeaderControlItem(HeaderControlItems* theHeaderControlItems);
            HWIN_EXPORT HeaderControlItem(HeaderControlItems* theHeaderControlItems, const String& theText);

            HWIN_EXPORT const HeaderControlItems* Items() const { return items; }
            HWIN_EXPORT HeaderControlItems* Items() { return items; }

            HWIN_EXPORT String Text() const;
            HWIN_EXPORT HeaderControlItem& SetText(const String& theText);

            HWIN_EXPORT HeaderControlItem& Assign(const HDITEM& item);
            HWIN_EXPORT const HeaderControlItem& AssignTo(HDITEM& item) const;

            HWIN_EXPORT size_t IndexOf() const;

            HWIN_EXPORT HeaderControlItem& ClearFilter();

        protected:
            HWIN_EXPORT virtual void DoOnBeginDrag( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnBeginFilterEdit( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnBeginTrack( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnDividerDoubleClick( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnDropDown( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnEndDrag( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnEndFilterEdit( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnEndTrack( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnFilterButtonClicked( NMHDFILTERBTNCLICK* pNMHDFILTERBTNCLICK );
            HWIN_EXPORT virtual void DoOnFilterChange( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnGetDispInfo( NMHDDISPINFO* pNMHDDISPINFO);
            HWIN_EXPORT virtual void DoOnItemChanged( NMHEADER* pNMHEADER);
            HWIN_EXPORT virtual void DoOnItemChanging( NMHEADER* pNMHEADER);
            HWIN_EXPORT virtual void DoOnItemClicked( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnItemDoubleClicked( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnItemKeyDown( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnItemStateIconClicked( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnItemOverflowButtonClicked( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnTrack( NMHEADER* pNMHEADER );
            HWIN_EXPORT virtual void DoOnCustomDraw( NMCUSTOMDRAW* pNMCUSTOMDRAW); 
            HWIN_EXPORT virtual void DoOnRightClicked( const Point& mousePosition );

        private:
            HWIN_EXPORT void InsertHDITEM();
            HWIN_EXPORT void UpdateHDITEM();
            HWIN_EXPORT void DeleteHDITEM();
        };

        // --------------------------------------------------------------------
        // HeaderControlItems
        // --------------------------------------------------------------------
        class HeaderControlItems
        {
        public:
            typedef size_t size_type;
            typedef std::shared_ptr<HeaderControlItem> value_type;
            typedef std::vector<value_type> vector;
            typedef vector::const_iterator const_iterator;
            typedef vector::iterator iterator;

            static const size_type npos = UINT64_MAX;
        private:
            friend class HeaderControlItem;
            friend class HeaderControl;
            HeaderControl* headerControl;
            vector items;
            size_type focusedIndex;

            void DoOnHandleCreated( );
        public:
            HWIN_EXPORT HeaderControlItems(HeaderControl* theHeaderControl);

            iterator begin() { return items.begin(); }
            iterator end() { return items.end(); }

            const_iterator begin() const { return items.begin(); }
            const_iterator end() const { return items.end(); }

            const_iterator cbegin() const { return items.cbegin(); }
            const_iterator cend() const { return items.cend(); }

            std::shared_ptr<HeaderControlItem>& at( size_type index ) { return items.at(index); }
            std::shared_ptr<HeaderControlItem> at( size_type index ) const { return items.at(index); }

            std::shared_ptr<HeaderControlItem>& operator[]( size_type index ) { return items[index]; }
            std::shared_ptr<HeaderControlItem> operator[]( size_type index ) const { return items[index]; }

            HWIN_EXPORT size_type Count() const;
            HWIN_EXPORT size_type count() const { return Count(); }
            HWIN_EXPORT size_type size() const { return Count(); }

            HWIN_EXPORT size_type IndexOf(const HeaderControlItem* theItem) const;
            HWIN_EXPORT size_type IndexOf(std::shared_ptr<const HeaderControlItem> theItem) const;

            HWIN_EXPORT std::shared_ptr<const HeaderControlItem> FocusedItem() const;
            HWIN_EXPORT std::shared_ptr<HeaderControlItem> FocusedItem();

            HWIN_EXPORT size_type FocusedIndex() const;

            HWIN_EXPORT std::shared_ptr<const HeaderControlItem> Add(const String& headerText);
            HWIN_EXPORT std::shared_ptr<const HeaderControlItem> Add(const String& headerText, HorizontalAlignment alignment);
            HWIN_EXPORT HeaderControlItems& RemoveAt( size_type index );



        };

        // --------------------------------------------------------------------
        // HeaderControl
        // --------------------------------------------------------------------
        class HeaderControl : public Control
        {
            friend class HeaderControlItem;
            HeaderControlItems* items;
            std::shared_ptr<ImageListHandle> imageList;
            std::shared_ptr<ImageListHandle> stateImageList;
            int bitmapMargin;
        public:
            typedef Control Base;
            HWIN_EXPORT HeaderControl();
            HWIN_EXPORT virtual ~HeaderControl();
            

            HWIN_EXPORT std::shared_ptr<ImageListHandle> ImageList() const;
            HWIN_EXPORT HeaderControl& SetImageList(const std::shared_ptr<ImageListHandle>& theImageList );

            HWIN_EXPORT std::shared_ptr<ImageListHandle> StateImageList() const;
            HWIN_EXPORT HeaderControl& SetStateImageList(const std::shared_ptr<ImageListHandle>& theImageList );

            HWIN_EXPORT Rectangle GetItemRectangle(size_t theIndex) const;
            HWIN_EXPORT Rectangle GetItemRectangle(const HeaderControlItem* theItem) const;
            HWIN_EXPORT Rectangle GetItemRectangle(std::shared_ptr<const HeaderControlItem> theItem) const;

            HWIN_EXPORT static int DefaultBitmapMargin();
            HWIN_EXPORT HeaderControl& SetBitmapMargin(int theMargin);


            const HeaderControlItems* Items() const { return items; };
            HeaderControlItems* Items() { return items; };

            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnBeginDrag;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnBeginFilterEdit;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnBeginTrack;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnDividerDoubleClick;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnDropDown;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnEndDrag;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnEndFilterEdit;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnEndTrack;
            boost::signals2::signal<void (HeaderControl* sender, NMHDFILTERBTNCLICK* pNMHDFILTERBTNCLICK, const std::shared_ptr<HeaderControlItem>& theItem ) > OnFilterButtonClicked;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnFilterChange;
            boost::signals2::signal<void (HeaderControl* sender, NMHDDISPINFO* pNMHDDISPINFO, const std::shared_ptr<HeaderControlItem>& theItem) > OnGetDispInfo;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem) > OnItemChanged;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem) > OnItemChanging;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnItemClicked;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnItemDoubleClicked;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnItemKeyDown;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnItemStateIconClicked;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnItemOverflowButtonClicked;
            boost::signals2::signal<void (HeaderControl* sender, NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem ) > OnTrack;
            boost::signals2::signal<void (HeaderControl* sender, NMCUSTOMDRAW* pNMCUSTOMDRAW) > OnCustomDraw;  
            boost::signals2::signal<void (HeaderControl* sender, const Point& mousePosition ) > OnRightClicked;
            boost::signals2::signal<void (HeaderControl* sender, const Point& mousePosition ) > OnCaptureReleased;

        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;

            HWIN_EXPORT virtual void DoOnHandleCreated( );
            HWIN_EXPORT virtual void DoOnWindowSubClassed( );

            HWIN_EXPORT virtual void DoOnBeginDrag( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnBeginFilterEdit( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnBeginTrack( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnDividerDoubleClick( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnDropDown( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnEndDrag( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnEndFilterEdit( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnEndTrack( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnFilterButtonClicked( NMHDFILTERBTNCLICK* pNMHDFILTERBTNCLICK, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnFilterChange( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnGetDispInfo( NMHDDISPINFO* pNMHDDISPINFO, const std::shared_ptr<HeaderControlItem>& theItem);
            HWIN_EXPORT virtual void DoOnItemChanged( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem);
            HWIN_EXPORT virtual void DoOnItemChanging( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem);
            HWIN_EXPORT virtual void DoOnItemClicked( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnItemDoubleClicked( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnItemKeyDown( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnItemStateIconClicked( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnItemOverflowButtonClicked( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnTrack( NMHEADER* pNMHEADER, const std::shared_ptr<HeaderControlItem>& theItem );
            HWIN_EXPORT virtual void DoOnCustomDraw( NMCUSTOMDRAW* pNMCUSTOMDRAW); 
            HWIN_EXPORT virtual void DoOnRightClicked( const Point& mousePosition );
            HWIN_EXPORT virtual void DoOnCaptureReleased( const Point& mousePosition );

            HWIN_EXPORT virtual void DoOnNotify(Message& message);
        };

        // --------------------------------------------------------------------
        // ListView
        // --------------------------------------------------------------------
        class ListView : public Control
        {
        public:
            typedef Control Base;
            HWIN_EXPORT ListView( );
            
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        // --------------------------------------------------------------------
        // MonthCalendar
        // --------------------------------------------------------------------
        class MonthCalendar : public Control
        {
        public:
            typedef Control Base;
            HWIN_EXPORT MonthCalendar( );
            
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        // --------------------------------------------------------------------
        // TreeEditBase
        // --------------------------------------------------------------------
        class TreeEditBase : public Control
        {
        public:
            typedef Control Base;
            HWIN_EXPORT TreeEditBase( );
        };


        // --------------------------------------------------------------------
        // EditBase
        // --------------------------------------------------------------------
        class EditBase : public Control
        {
        public:
            typedef Control Base;

            HWIN_EXPORT EditBase( );
        };


        // --------------------------------------------------------------------
        // TextEditBase
        // --------------------------------------------------------------------
        class TextEditBase : public EditBase
        {
        public:
            typedef EditBase Base;
            HWIN_EXPORT TextEditBase( );
        };

        enum class TextEditStyles
        {
            AlignLeft = ES_LEFT,
            AlignCenter = ES_CENTER,
            AlignRight = ES_RIGHT,
            MultiLine = ES_MULTILINE,
            ConvertToUpperCase = ES_UPPERCASE,
            ConvertToLowerCase = ES_LOWERCASE,
            Password = ES_PASSWORD,
            AutomaticVerticalScroll = ES_AUTOVSCROLL,
            AutomaticHorizontalScroll = ES_AUTOHSCROLL,
            AlwaysShowSelection = ES_NOHIDESEL,
            OEMConvert = ES_OEMCONVERT,
            ReadOnly = ES_READONLY,
            WantReturn = ES_WANTRETURN,
            Numeric = ES_NUMBER
        };

        // --------------------------------------------------------------------
        // TextEdit
        // --------------------------------------------------------------------
        class TextEdit : public TextEditBase
        {
            HorizontalAlignment alignment;
        public:
            typedef TextEditBase Base;
            HWIN_EXPORT TextEdit( );
            

            
            HWIN_EXPORT bool CanUndo() const;
            HWIN_EXPORT TextEdit& Undo();

            HWIN_EXPORT TextEdit& EmptyUndoBuffer();
            HWIN_EXPORT TextEdit& FmtLines(bool addSoftLinebreaks);

            HWIN_EXPORT String CueBannerText( ) const;
            HWIN_EXPORT TextEdit& SetCueBannerText(const String& theText, bool displayWhileFocused = false );
            HWIN_EXPORT TextEdit& SetCueBannerText(const wchar_t* theText, bool displayWhileFocused = false );

            HWIN_EXPORT int GetFirstVisibleLine() const;
            HWIN_EXPORT UINT TextLimit() const;
            HWIN_EXPORT TextEdit& SetTextLimit(UINT theValue);

            
            HWIN_EXPORT int LineIndex(int theIndex) const;
            HWIN_EXPORT int LineLength(int theIndex) const;
            HWIN_EXPORT String Line(int theIndex) const;
            HWIN_EXPORT int LineCount() const;
            HWIN_EXPORT bool IsModified() const;

            HWIN_EXPORT wchar_t PasswordChar() const;
            HWIN_EXPORT TextEdit& SetPasswordChar(wchar_t theValue );

            HWIN_EXPORT Range Selection() const;
            HWIN_EXPORT TextEdit& SetSelection(const Range& selectionRange );

            HWIN_EXPORT TextEdit& ReplaceSelection(const String& theText);
            HWIN_EXPORT TextEdit& ReplaceSelection(const wchar_t* theText);

            HWIN_EXPORT TextEdit& Append(const String& theText);
            HWIN_EXPORT TextEdit& Append(const wchar_t* theText);



        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;

            HWIN_EXPORT virtual void DoOnSetEnabled(bool theValue);
            
        };

        // --------------------------------------------------------------------
        // MemoEdit
        // --------------------------------------------------------------------
        class MemoEdit : public TextEdit
        {
        public:
            typedef TextEdit Base;
            HWIN_EXPORT MemoEdit( );

            HWIN_EXPORT int FirstVisibleLine() const;
            HWIN_EXPORT MemoEdit& AppendLine(const String& theText);
            HWIN_EXPORT MemoEdit& AppendLine(const wchar_t* theText);
        protected:
            HWIN_EXPORT virtual DWORD GetStyle() const;
            /*
            HWIN_EXPORT virtual String Text() const;
        protected:
            HWIN_EXPORT HLOCAL GetHandle() const;
            */
        };


        // --------------------------------------------------------------------
        // HotKey
        // --------------------------------------------------------------------
        class HotKey : public TextEditBase
        {
        public:
            typedef TextEditBase Base;
            HWIN_EXPORT HotKey( );
            
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        // --------------------------------------------------------------------
        // ScrollBar
        // --------------------------------------------------------------------
        class ScrollBar : public Control
        {
        public:
            typedef Control Base;
            HWIN_EXPORT ScrollBar( );
            
        protected:
            HWIN_EXPORT virtual std::shared_ptr<WindowClass> GetWindowClass() const;
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };

        // --------------------------------------------------------------------
        // HScrollBar
        // --------------------------------------------------------------------
        class HScrollBar : public ScrollBar
        {
        public:
            typedef ScrollBar Base;
            HWIN_EXPORT HScrollBar( );
        protected:
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };

        // --------------------------------------------------------------------
        // VScrollBar
        // --------------------------------------------------------------------
        class VScrollBar : public ScrollBar
        {
        public:
            typedef ScrollBar Base;
            HWIN_EXPORT VScrollBar( );
        protected:
            HWIN_EXPORT virtual DWORD GetStyle() const;
        };


        // --------------------------------------------------------------------
        // Timer
        // --------------------------------------------------------------------
        class Timer : public Component
        {
            TimeSpan interval;
            bool enabled;

            friend class TimerControl;
            class TimerControl : public Control
            {
                std::weak_ptr<Timer> timer;
                UINT_PTR timerId;
                static UINT_PTR TimerID; 
                bool stoppingTimer;
            public:
                typedef Control Base;
                HWIN_EXPORT TimerControl(const std::shared_ptr<Timer> theTimer);

                HWIN_EXPORT virtual void HandleMessage(Message& message);

                HWIN_EXPORT void StopTimer();
                HWIN_EXPORT void StartTimer();



            protected:
                HWIN_EXPORT virtual DWORD GetStyle() const;
                HWIN_EXPORT virtual HWND CreateHandle( );
                HWIN_EXPORT virtual void DoBeforeHandleDestroy( );

            };

            std::shared_ptr<TimerControl> timerControl;

        public:
            typedef Component Base;

            HWIN_EXPORT Timer();

            HWIN_EXPORT TimeSpan Interval() const;
            HWIN_EXPORT Timer& SetInterval(TimeSpan& theInterval);

            HWIN_EXPORT bool Enabled() const;
            HWIN_EXPORT Timer& SetEnabled(bool theValue = true);

            boost::signals2::signal<void (Timer* sender)> OnTick;
        protected:
            HWIN_EXPORT virtual void DoOnTick();

        };



    };
};
#endif //__HWINSTDCTRLS_H__